package com.dd.cloud.user.service.doctor.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.config.common.ProfilesProperties;
import com.dd.cloud.common.config.sms.SmsComponent;
import com.dd.cloud.common.constants.HealthConstants;
import com.dd.cloud.common.constants.OrderConstants;
import com.dd.cloud.common.constants.SmsConstants;
import com.dd.cloud.common.constants.ZekeConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.Assert;
import com.dd.cloud.common.utils.BigDecimalUtils;
import com.dd.cloud.common.utils.ExtUtils;
import com.dd.cloud.common.utils.SerialNumberUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.doctor.*;
import com.dd.cloud.user.mapper.doctor.DoctorOrderIncomeDetailMapper;
import com.dd.cloud.user.mapper.doctor.DoctorWithdrawRecordMapper;
import com.dd.cloud.user.mq.MQConfig;
import com.dd.cloud.user.req.doctor.DoctorWithdrawIncomeReq;
import com.dd.cloud.user.req.doctor.DoctorWithdrawPaymentReq;
import com.dd.cloud.user.req.doctor.DoctorWithdrawRecordPageReq;
import com.dd.cloud.user.req.doctor.DoctorWithdrawRecordPageSystemReq;
import com.dd.cloud.user.res.doctor.*;
import com.dd.cloud.user.service.doctor.*;
import com.dd.cloud.user.service.news.INewsInfoService;
import com.spire.pdf.htmlconverter.qt.ILogInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Lx
 * @version 1.0
 */
@Slf4j
@Service
public class DoctorWithdrawRecordServiceImpl extends ServiceImpl<DoctorWithdrawRecordMapper, DoctorWithdrawRecord> implements IDoctorWithdrawRecordService {
    @Autowired
    private SmsComponent smsComponent;
    @Autowired
    private INewsInfoService newsInfoService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private IDoctorBankService doctorBankService;
    @Autowired
    private IDoctorUserService doctorUserService;
    @Autowired
    private ProfilesProperties profilesProperties;
    @Autowired
    private IDoctorOrderIncomeDetailService doctorOrderIncomeDetailService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private DoctorOrderIncomeDetailMapper doctorOrderIncomeDetailMapper;
    @Autowired
    private IDoctorOrderIncomeWithdrawalLinkService doctorOrderIncomeWithdrawalLinkService;
    @Autowired
    private IDoctorWithdrawRecordService doctorWithdrawRecordService;


    /**
     * 税比例
     */
    public final static BigDecimal taxRate = new BigDecimal("0.035");

    /**
     * 医生申请提现收入
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doctorWithdrawIncome(DoctorWithdrawIncomeReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        if (StringUtils.isBlank(req.getPhone())) {
            DoctorUser doctorUser = doctorUserService.getById(loginInfo.getId());
            req.setPhone(doctorUser.getMobileNumber());
        }
        if (!"194711".equals(req.getCode()) || ZekeConstants.ProfilesType.PROD.equals(profilesProperties.getActive())) {
            // 校验验证码
            smsComponent.verifyPhoneCode(req.getPhone(), req.getCode());
        }
        DoctorWithdrawIncomeInfoRes res = doctorOrderIncomeDetailService.queryDoctorWithdrawIncomeInfo(loginInfo.getId());
        if (req.getWithdrawAmount() > res.getCanWithdrawIncome()) {
            throw new ZekeException(400, "可提现金额不足");
        }
        String withdrawNo = SerialNumberUtils.getInstance().generateSerialNumber(redisTemplate, "TX");
        DoctorBankRes bankRes = doctorBankService.getDoctorBank();
        if (bankRes == null || StringUtils.isBlank(bankRes.getBankNumber())) {
            throw new ZekeException(400, "请先绑定银行卡");
        }
        DoctorWithdrawRecord doctorWithdrawRecord = new DoctorWithdrawRecord();
        doctorWithdrawRecord.setWithdrawNo(withdrawNo);
        doctorWithdrawRecord.setDoctorId(loginInfo.getId());
        doctorWithdrawRecord.setCreateDate(LocalDateTime.now());
        doctorWithdrawRecord.setBankType(bankRes.getType());
        doctorWithdrawRecord.setBankNumber(bankRes.getBankNumber());
        doctorWithdrawRecord.setBankProvince(bankRes.getProvince());
        doctorWithdrawRecord.setBankCity(bankRes.getCity());
        doctorWithdrawRecord.setAccountOpeningBank(bankRes.getAccountOpeningBank());
        doctorWithdrawRecord.setType(OrderConstants.DoctorWithdrawType.HAND_BANK);
        doctorWithdrawRecord.setStatus(OrderConstants.DoctorWithdrawStatus.HANDLE_IN);
        doctorWithdrawRecord.setTaxRate(taxRate.multiply(BigDecimal.valueOf(100)));
        doctorWithdrawRecord.setAfterTaxAmount(req.getWithdrawAmount());
        doctorWithdrawRecord.setTaxFee(BigDecimalUtils.multiply(BigDecimal.valueOf(req.getWithdrawAmount()), taxRate, 0).intValue());
        doctorWithdrawRecord.setAmount(doctorWithdrawRecord.getAfterTaxAmount() + doctorWithdrawRecord.getTaxFee());
        doctorWithdrawRecord.setResidueCanWithdrawIncome(res.getCanWithdrawIncome() - req.getWithdrawAmount());
        Boolean flag = save(doctorWithdrawRecord);
        if (flag) {
            //记录提现明细
            saveIncomeDetail(loginInfo.getId(), doctorWithdrawRecord.getWithdrawNo(), doctorWithdrawRecord.getAmount());
        }

        if (profilesProperties.getActive().equals(HealthConstants.ProfilesType.PROD)) {
            //生产环境, 发短信提醒
            /**
             * 发送提现通知短信 发送给财务
             */
            String[] ph = new String[]{"13417487342", "18923756284"};
            for (String phone : ph) {
                Map<String, String> msg = new HashMap<>();
                msg.put("phone", phone);
                msg.put("name", bankRes.getDoctorName());
                String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                msg.put("date", date);
                msg.put("param_type", SmsConstants.ParamType.JSON);
                msg.put("sms_template", SmsConstants.Template.WIDTHDRAW_FINANCE_NEWS);
                amqpTemplate.convertAndSend(MQConfig.SMS_EXCHANGE, MQConfig.SMS_KEY, msg);
            }
        } else if (profilesProperties.getActive().equals(HealthConstants.ProfilesType.TEST)) {
            //测试环境, 发送短信给测试
            Map<String, String> msg = new HashMap<>();
            msg.put("phone", "19974324119");
            msg.put("name", bankRes.getDoctorName());
            String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            msg.put("date", date);
            msg.put("param_type", SmsConstants.ParamType.JSON);
            msg.put("sms_template", SmsConstants.Template.WIDTHDRAW_FINANCE_NEWS);
            amqpTemplate.convertAndSend(MQConfig.SMS_EXCHANGE, MQConfig.SMS_KEY, msg);
        }

    }


    private void saveIncomeDetail(Integer doctorId, String withdrawNo, Integer amount) {
        List<DoctorOrderIncomeDetail> doctorOrderIncomeDetails = doctorOrderIncomeDetailMapper.queryIncomeDetail(doctorId);
        List<DoctorOrderIncomeDetail> doctorOrderIncomeDetailList = new ArrayList<>();
        List<DoctorOrderIncomeWithdrawalLink> withdrawRecordList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeDetails)) {
            for (int i = 0; i < doctorOrderIncomeDetails.size(); i++) {
                DoctorOrderIncomeDetail item = doctorOrderIncomeDetails.get(i);
                Integer income = item.getIncome();
                Integer withdrawalAmount = item.getWithdrawalAmount();
                income = income - withdrawalAmount;
                log.info("扣除收益,收益id为:{},收益金额为:{},需要抵扣的金额为:{},提现金额:{}", item.getId(), income, amount, withdrawalAmount);
                if (income <= 0) {
                    continue;
                }
                if (amount >= income) {
                    amount = amount - income;
                    log.info("需要扣除的id:{},金额:{}", item.getId(), income);
                    DoctorOrderIncomeDetail doctorOrderIncomeDetail = new DoctorOrderIncomeDetail();
                    doctorOrderIncomeDetail.setId(item.getId()).setSettlementStatus(OrderConstants.DoctorSettlementStatus.SETTLEMENT).setWithdrawalAmount(income + withdrawalAmount);
                    doctorOrderIncomeDetailList.add(doctorOrderIncomeDetail);
                    DoctorOrderIncomeWithdrawalLink withdrawalLink = new DoctorOrderIncomeWithdrawalLink();
                    withdrawalLink.setIncomeId(item.getId()).setWithdrawNo(withdrawNo).setCreateDate(LocalDateTime.now()).setStatus(OrderConstants.DoctorWithdrawStatus.HANDLE_IN).setMoney(income);
                    withdrawRecordList.add(withdrawalLink);
                } else {
                    DoctorOrderIncomeDetail doctorOrderIncomeDetail = new DoctorOrderIncomeDetail();
                    doctorOrderIncomeDetail.setId(item.getId()).setWithdrawalAmount(amount + withdrawalAmount).setSettlementStatus(OrderConstants.DoctorSettlementStatus.WAIT_SETTLEMENT);
                    DoctorOrderIncomeWithdrawalLink withdrawalLink = new DoctorOrderIncomeWithdrawalLink();
                    withdrawalLink.setIncomeId(item.getId()).setWithdrawNo(withdrawNo).setCreateDate(LocalDateTime.now()).setStatus(OrderConstants.DoctorWithdrawStatus.HANDLE_IN).setMoney(amount);
                    withdrawRecordList.add(withdrawalLink);
                    amount = amount - income;
                }
                if (amount <= 0) {
                    break;
                }
            }
        }
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeDetailList)) {
            Boolean flag = doctorOrderIncomeDetailService.updateBatchById(doctorOrderIncomeDetailList);
            if (!flag) {
                log.info("更新失败~");
            }
        }
        if (CollectionUtil.isNotEmpty(withdrawRecordList)) {
//                dp.saveBatch(withdrawRecordList);
            Boolean flag = doctorOrderIncomeWithdrawalLinkService.saveBatch(withdrawRecordList);
            if (!flag) {
                log.info("保存失败");
            }
        }
    }

    /**
     * 医生查询提现记录
     *
     * @param req
     * @return
     */
    @Override
    public IPage<DoctorWithdrawRecordPageRes> queryDoctorWithdrawRecordPage(DoctorWithdrawRecordPageReq req) {
        if (req.getDoctorId() == null) {
            req.setDoctorId(UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get().getId());
        }
        IPage<DoctorWithdrawRecordPageRes> iPage = req.pagePojo();
        iPage = getBaseMapper().queryDoctorWithdrawRecordPage(iPage, req);
        return iPage;
    }

    /**
     * 查询提现记录详情
     *
     * @param withdrawNo
     * @return
     */
    @Override
    public DoctorWithdrawRecordDetailRes queryDoctorWithdrawRecordDetail(String withdrawNo) {
        DoctorWithdrawRecordDetailRes res = getBaseMapper().queryDoctorWithdrawRecordDetail(withdrawNo);
        if (res != null) {
            res.setIncomeInfoRes(doctorOrderIncomeDetailService.queryDoctorWithdrawIncomeInfo(res.getDoctorId()));
        }
        return res;
    }

    /**
     * 查询所有医生提现记录 运营后台
     *
     * @param req
     * @return
     */
    @Override
    public IPage<DoctorWithdrawRecordPageSystemRes> queryDoctorWithdrawRecordPageSystem(DoctorWithdrawRecordPageSystemReq req) {
        Assert.verifyStatusIdsParam(req.getClass(), req);
        req.setListType(req.getListType() == null ? 1 : req.getListType());
        if (req.getListType() == 2) {
            req.setStart(LocalDate.now().minusDays(1).atTime(16, 0));
            req.setEnd(req.getStart().plusDays(1).minusSeconds(1));
        } else if (req.getListType() == 3) {
            req.setStart(LocalDate.now().atTime(16, 0));
            req.setEnd(LocalDateTime.now());
            if (req.getStart().isAfter(req.getEnd())) {
                req.setEnd(req.getStart());
            }
        }
        IPage<DoctorWithdrawRecordPageSystemRes> iPage = req.pagePojo();
        iPage = getBaseMapper().queryDoctorWithdrawRecordPageSystem(iPage, req);
        return iPage;
    }

    /**
     * 查询所有医生提现记录 运营后台 导出excel
     *
     * @param response
     * @param req
     * @return
     */
    @Override
    public void exportDoctorWithdrawRecordPageSystemExcel(HttpServletResponse response, DoctorWithdrawRecordPageSystemReq req) {
        req.setPage(1);
        req.setPageSize(100);
        int no = 1;
        List<DoctorWithdrawRecordExcelRes> listRes = new ArrayList<>(100);
        IPage<DoctorWithdrawRecordPageSystemRes> iPage;
        do {
            iPage = queryDoctorWithdrawRecordPageSystem(req);
            for (DoctorWithdrawRecordPageSystemRes item : iPage.getRecords()) {
                DoctorWithdrawRecordExcelRes res = new DoctorWithdrawRecordExcelRes();
                BeanUtils.copyProperties(item, res);
                res.setAmount(BigDecimalUtils.divide(item.getAmount(), 100));
                res.setAfterTaxAmount(BigDecimalUtils.divide(item.getAfterTaxAmount(), 100));
                res.setTaxFee(BigDecimalUtils.divide(item.getTaxFee(), 100));
                res.setResidueCanWithdrawIncome(BigDecimalUtils.divide(item.getResidueCanWithdrawIncome(), 100));
                res.setAccountOpeningBank(res.getBankType() + res.getAccountOpeningBank());
                switch (item.getStatus()) {
                    case OrderConstants.DoctorWithdrawStatus.SUCCESS:
                        res.setStatus("打款成功");
                        break;
                    case OrderConstants.DoctorWithdrawStatus.FAIL:
                        res.setStatus("打款失败");
                        break;
                    case OrderConstants.DoctorWithdrawStatus.HANDLE_IN:
                        res.setStatus("待打款");
                        break;
                    default:
                }
//                res.setNo(no);
                listRes.add(res);
                no++;
            }
            req.setPage(req.getPage() + 1);
        } while (iPage.getCurrent() < iPage.getPages());
        String title = "医生提现明细报表";
        try {
            ExtUtils.exportExcel(listRes, title, title, DoctorWithdrawRecordExcelRes.class, title, true, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询单个医生提现记录 运营后台 导出excel
     *
     * @param response
     * @param req
     * @return
     */
    @Override
    public void exportSingleDoctorWithdrawRecordPageSystemExcel(HttpServletResponse response, DoctorWithdrawRecordPageSystemReq req) {
        req.setPage(1);
        req.setPageSize(100);
        req.setListType(null);
        req.setMechanId(null);
        if (StringUtils.isBlank(req.getDoctorId())) {
            throw new ZekeException(400, "医生id不能为空");
        }
        List<SingleDoctorWithdrawRecordExcelRes> listRes = new ArrayList<>(100);
        IPage<DoctorWithdrawRecordPageSystemRes> iPage;
        String name = null;
        do {
            iPage = queryDoctorWithdrawRecordPageSystem(req);
            for (DoctorWithdrawRecordPageSystemRes item : iPage.getRecords()) {
                if (name == null) {
                    name = item.getDoctorName();
                }
                SingleDoctorWithdrawRecordExcelRes res = new SingleDoctorWithdrawRecordExcelRes();
                BeanUtils.copyProperties(item, res);
                res.setAmount(BigDecimalUtils.divide(item.getAmount(), 100));
                res.setAfterTaxAmount(BigDecimalUtils.divide(item.getAfterTaxAmount(), 100));
                res.setTaxFee(BigDecimalUtils.divide(item.getTaxFee(), 100));
                res.setResidueCanWithdrawIncome(BigDecimalUtils.divide(item.getResidueCanWithdrawIncome(), 100));
                res.setAccountOpeningBank(res.getBankType() + res.getAccountOpeningBank());
                switch (item.getStatus()) {
                    case OrderConstants.DoctorWithdrawStatus.SUCCESS:
                        res.setStatus("打款成功");
                        break;
                    case OrderConstants.DoctorWithdrawStatus.FAIL:
                        res.setStatus("打款失败");
                        break;
                    case OrderConstants.DoctorWithdrawStatus.HANDLE_IN:
                        res.setStatus("待打款");
                        break;
                    default:
                }
                listRes.add(res);
            }
            req.setPage(req.getPage() + 1);
        } while (iPage.getCurrent() < iPage.getPages());
        String title = name + "医生提现明细报表";
        try {
            ExtUtils.exportExcel(listRes, title, title, SingleDoctorWithdrawRecordExcelRes.class, title, true, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 医生申请提现 后台打款
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doctorWithdrawPayment(DoctorWithdrawPaymentReq req) {
        DoctorWithdrawRecord doctorWithdrawRecord = getById(req.getWithdrawNo());
        if (doctorWithdrawRecord == null) {
            throw new ZekeException(400, "提现记录不存在");
        }
        if (doctorWithdrawRecord.getStatus() != OrderConstants.DoctorWithdrawStatus.HANDLE_IN) {
            throw new ZekeException(400, "提现记录未在待处理状态,请勿重复进行打款操作");
        }
        LambdaQueryWrapper<DoctorOrderIncomeWithdrawalLink> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DoctorOrderIncomeWithdrawalLink::getWithdrawNo, req.getWithdrawNo()).eq(DoctorOrderIncomeWithdrawalLink::getStatus, 3);
        List<DoctorOrderIncomeWithdrawalLink> doctorOrderIncomeWithdrawalLinks = doctorOrderIncomeWithdrawalLinkService.list(queryWrapper);
        List<DoctorOrderIncomeDetail> orderFailIncomeDetails = new ArrayList<>();
        List<DoctorOrderIncomeDetail> orderIncomeDetailList = null;
        List<Integer> incomeList = null;
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeWithdrawalLinks)) {
            incomeList = doctorOrderIncomeWithdrawalLinks.stream().map(DoctorOrderIncomeWithdrawalLink::getIncomeId).collect(Collectors.toList());
            LambdaQueryWrapper<DoctorOrderIncomeDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(DoctorOrderIncomeDetail::getId, incomeList).in(DoctorOrderIncomeDetail::getSettlementStatus, 1,2);
            orderIncomeDetailList = doctorOrderIncomeDetailService.list(lambdaQueryWrapper);
        }
//        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setId(1);
        loginInfo.setName("测试");
        DoctorWithdrawRecord update = new DoctorWithdrawRecord();
        if (req.getStatus() == OrderConstants.DoctorWithdrawStatus.SUCCESS) {
            if (StringUtils.isBlank(req.getPayProof()) && StringUtils.isBlank(req.getPayAnnex())) {
                throw new ZekeException(400, "打款成功必须上传凭证或附件");
            }
            if (CollectionUtil.isNotEmpty(orderIncomeDetailList)) {
                List<Integer> withdrawalIds = doctorOrderIncomeWithdrawalLinks.stream().map(DoctorOrderIncomeWithdrawalLink::getId).collect(Collectors.toList());
                for (DoctorOrderIncomeDetail item : orderIncomeDetailList) {
                    Integer incomeId = item.getId();
                    LambdaQueryWrapper<DoctorOrderIncomeWithdrawalLink> qw = new LambdaQueryWrapper<>();
                    qw.eq(DoctorOrderIncomeWithdrawalLink::getIncomeId, incomeId).in(DoctorOrderIncomeWithdrawalLink::getStatus, 3)
                            .notIn(DoctorOrderIncomeWithdrawalLink::getId, withdrawalIds);
                    List<DoctorOrderIncomeWithdrawalLink> doctorOrderIncomeWithdrawalLinkList = doctorOrderIncomeWithdrawalLinkService.list(qw);
                    if (CollectionUtil.isEmpty(doctorOrderIncomeWithdrawalLinkList)) {
                        item.setSettlementStatus(OrderConstants.DoctorSettlementStatus.ACCOMPLISH_SETTLEMENT);
                    }

                }
            }
            if (CollectionUtil.isNotEmpty(doctorOrderIncomeWithdrawalLinks)) {
                doctorOrderIncomeWithdrawalLinks.stream().forEach(item -> {
                    item.setStatus(OrderConstants.DoctorWithdrawStatus.SUCCESS);
                });
            }
            update.setPaymentTime(LocalDateTime.now());
        } else if (req.getStatus() == OrderConstants.DoctorWithdrawStatus.FAIL) {
            if (StringUtils.isBlank(req.getPayFailReason())) {
                throw new ZekeException(400, "打款失败必须说明失败原因");
            }
            if (CollectionUtil.isNotEmpty(doctorOrderIncomeWithdrawalLinks)) {
                doctorOrderIncomeWithdrawalLinks.stream().forEach(item -> item.setStatus(OrderConstants.DoctorWithdrawStatus.FAIL));
                Map<Integer, List<DoctorOrderIncomeWithdrawalLink>> map = doctorOrderIncomeWithdrawalLinks.stream()
                        .collect(Collectors.groupingBy(DoctorOrderIncomeWithdrawalLink::getIncomeId));
                for (Integer key : map.keySet()) {
                    List<DoctorOrderIncomeWithdrawalLink> list = map.get(key);
                    Integer sum = list.stream().mapToInt(DoctorOrderIncomeWithdrawalLink::getMoney).sum();
                    DoctorOrderIncomeWithdrawalLink doctorOrderIncomeWithdrawalLink = list.get(0);
                    orderIncomeDetailList.stream().forEach(item -> {
                        if (item.getId().equals(doctorOrderIncomeWithdrawalLink.getIncomeId())) {
                            if (item.getWithdrawalAmount() >= sum) {
                                item.setWithdrawalAmount(item.getWithdrawalAmount() - sum);
                                item.setSettlementStatus(OrderConstants.DoctorSettlementStatus.WAIT_SETTLEMENT);
                            }
                        }
                    });
                }
            }
        }
        update.setWithdrawNo(req.getWithdrawNo());
        update.setStatus(req.getStatus());
        update.setPayProof(req.getPayProof());
        update.setPayAnnex(req.getPayAnnex());
        update.setPayFailReason(req.getPayFailReason());
        update.setUpdateDate(LocalDateTime.now());
        update.setPayOperId(loginInfo.getId());
        update.setPayOperName(loginInfo.getName());
        updateById(update);
        if (CollectionUtil.isNotEmpty(orderIncomeDetailList)) {
            Boolean flag = doctorOrderIncomeDetailService.updateBatchById(orderIncomeDetailList);
            if (!flag) {
                log.info("更新数据失败");
            }
        }
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeWithdrawalLinks)) {
            Boolean flag = doctorOrderIncomeWithdrawalLinkService.updateBatchById(doctorOrderIncomeWithdrawalLinks);
            if (!flag) {
                log.info("更新数据失败");
            }
        }
        newsInfoService.sendDoctorWithdrawPaymentNotice(doctorWithdrawRecord.getDoctorId(), doctorWithdrawRecord.getAfterTaxAmount(), req.getPayFailReason(), req.getStatus());
    }


    @Override
    public void testIncomeTest() {
        LambdaQueryWrapper<DoctorWithdrawRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(DoctorWithdrawRecord::getCreateDate);
        List<DoctorWithdrawRecord> withdrawRecordList = doctorWithdrawRecordService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(withdrawRecordList)) {
            List<DoctorWithdrawRecord> successList = withdrawRecordList.stream().filter(item -> item.getStatus() == 1).collect(Collectors.toList());
//            List<DoctorWithdrawRecord> failList = withdrawRecordList.stream().filter(item -> item.getStatus() == 2).collect(Collectors.toList());
            List<DoctorWithdrawRecord> waitingList = withdrawRecordList.stream().filter(item -> item.getStatus() == 3).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(successList)) {
                successList.stream().forEach(item -> {
                    successIncomeDetail(item.getDoctorId(), item.getWithdrawNo(), item.getAmount());
                });
            }
            if (CollectionUtil.isNotEmpty(waitingList)) {
                waitingList.stream().forEach(item -> {
                    waitingIncomeDeatil(item.getDoctorId(), item.getWithdrawNo(), item.getAmount());
                });
            }
//            if (CollectionUtil.isNotEmpty(failList)) {
//                failList.stream().forEach(item->item);
//            }
        }
    }

    private void waitingIncomeDeatil(Integer doctorId, String withdrawNo, Integer amount) {
        List<DoctorOrderIncomeDetail> doctorOrderIncomeDetails = doctorOrderIncomeDetailMapper.queryIncomeDetail(doctorId);
        List<DoctorOrderIncomeDetail> doctorOrderIncomeDetailList = new ArrayList<>();
        List<DoctorOrderIncomeWithdrawalLink> withdrawRecordList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeDetails)) {
            for (int i = 0; i < doctorOrderIncomeDetails.size(); i++) {
                DoctorOrderIncomeDetail item = doctorOrderIncomeDetails.get(i);
                Integer income = item.getIncome();
                Integer withdrawalAmount = item.getWithdrawalAmount();
                income = income - withdrawalAmount;
                log.info("扣除收益,收益id为:{},收益金额为:{},需要抵扣的金额为:{},提现金额:{}", item.getId(), income, amount, withdrawalAmount);
                if (income <= 0) {
                    continue;
                }
                log.info("扣除收益,收益id为:{},收益金额为:{},需要抵扣的金额为:{}", item.getId(), income, amount);
                if (amount >= income) {
                    amount = amount - income;
                    log.info("需要扣除的id:{},金额:{}", item.getId(), income);
                    DoctorOrderIncomeDetail doctorOrderIncomeDetail = new DoctorOrderIncomeDetail();
                    doctorOrderIncomeDetail.setId(item.getId())
                            .setSettlementStatus(OrderConstants.DoctorSettlementStatus.SETTLEMENT)
                            .setWithdrawalAmount(income + item.getWithdrawalAmount());
                    doctorOrderIncomeDetailList.add(doctorOrderIncomeDetail);
                    DoctorOrderIncomeWithdrawalLink withdrawalLink = new DoctorOrderIncomeWithdrawalLink();
                    withdrawalLink.setIncomeId(item.getId())
                            .setWithdrawNo(withdrawNo)
                            .setCreateDate(LocalDateTime.now())
                            .setStatus(OrderConstants.DoctorWithdrawStatus.HANDLE_IN)
                            .setMoney(income);
                    withdrawRecordList.add(withdrawalLink);
                } else {
                    DoctorOrderIncomeDetail doctorOrderIncomeDetail = new DoctorOrderIncomeDetail();
                    doctorOrderIncomeDetail.setId(item.getId()).setWithdrawalAmount(amount + item.getWithdrawalAmount()).setSettlementStatus(OrderConstants.DoctorSettlementStatus.WAIT_SETTLEMENT);
                    DoctorOrderIncomeWithdrawalLink withdrawalLink = new DoctorOrderIncomeWithdrawalLink();
                    withdrawalLink.setIncomeId(item.getId())
                            .setWithdrawNo(withdrawNo)
                            .setCreateDate(LocalDateTime.now())
                            .setStatus(OrderConstants.DoctorWithdrawStatus.HANDLE_IN)
                            .setMoney(amount);
                    withdrawRecordList.add(withdrawalLink);
                    amount = amount - income;
                }
                if (amount <= 0) {
                    break;
                }
            }
        }
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeDetailList)) {
            Boolean flag = doctorOrderIncomeDetailService.updateBatchById(doctorOrderIncomeDetailList);
            if (!flag) {
                log.info("更新失败~");
            }
        }
        if (CollectionUtil.isNotEmpty(withdrawRecordList)) {
//                dp.saveBatch(withdrawRecordList);
            Boolean flag = doctorOrderIncomeWithdrawalLinkService.saveBatch(withdrawRecordList);
            if (!flag) {
                log.info("保存失败");
            }
        }
    }

    @Override
    public void testIncomeTest01() {
        LambdaQueryWrapper<DoctorOrderIncomeDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DoctorOrderIncomeDetail::getRefund, 1).eq(DoctorOrderIncomeDetail::getStatus, 3);
        List<DoctorOrderIncomeDetail> list = doctorOrderIncomeDetailService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            list.stream().forEach(item -> item.setSettlementStatus(OrderConstants.DoctorSettlementStatus.NO_ONE_SETTLEMENT));
            doctorOrderIncomeDetailService.updateBatchById(list);
        }
    }


    private void successIncomeDetail(Integer doctorId, String withdrawNo, Integer amount) {
        List<DoctorOrderIncomeDetail> doctorOrderIncomeDetails = doctorOrderIncomeDetailMapper.queryIncomeDetail(doctorId);
        List<DoctorOrderIncomeDetail> doctorOrderIncomeDetailList = new ArrayList<>();
        List<DoctorOrderIncomeWithdrawalLink> withdrawRecordList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeDetails)) {
            for (int i = 0; i < doctorOrderIncomeDetails.size(); i++) {
                DoctorOrderIncomeDetail item = doctorOrderIncomeDetails.get(i);
                Integer income = item.getIncome();
                Integer withdrawalAmount = item.getWithdrawalAmount();
                income = income - withdrawalAmount;
                log.info("扣除收益,收益id为:{},收益金额为:{},需要抵扣的金额为:{},提现金额:{}", item.getId(), income, amount, withdrawalAmount);
                if (income <= 0) {
                    continue;
                }
                log.info("扣除收益,收益id为:{},收益金额为:{},需要抵扣的金额为:{}", item.getId(), income, amount);
                if (amount >= income) {
                    amount = amount - income;
                    log.info("需要扣除的id:{},金额:{}", item.getId(), income);
                    DoctorOrderIncomeDetail doctorOrderIncomeDetail = new DoctorOrderIncomeDetail();
                    doctorOrderIncomeDetail.setId(item.getId()).setSettlementStatus(OrderConstants.DoctorSettlementStatus.ACCOMPLISH_SETTLEMENT).setWithdrawalAmount(income + item.getWithdrawalAmount());
                    doctorOrderIncomeDetailList.add(doctorOrderIncomeDetail);
                    DoctorOrderIncomeWithdrawalLink withdrawalLink = new DoctorOrderIncomeWithdrawalLink();
                    withdrawalLink.setIncomeId(item.getId()).setWithdrawNo(withdrawNo).setCreateDate(LocalDateTime.now()).setStatus(OrderConstants.DoctorWithdrawStatus.SUCCESS).setMoney(income);
                    withdrawRecordList.add(withdrawalLink);
                } else {
                    DoctorOrderIncomeDetail doctorOrderIncomeDetail = new DoctorOrderIncomeDetail();
                    doctorOrderIncomeDetail.setId(item.getId())
                            .setWithdrawalAmount(amount + item.getWithdrawalAmount())
                            .setSettlementStatus(OrderConstants.DoctorSettlementStatus.WAIT_SETTLEMENT);
                    DoctorOrderIncomeWithdrawalLink withdrawalLink = new DoctorOrderIncomeWithdrawalLink();
                    withdrawalLink.setIncomeId(item.getId()).setWithdrawNo(withdrawNo).setCreateDate(LocalDateTime.now()).setStatus(OrderConstants.DoctorWithdrawStatus.SUCCESS).setMoney(amount);
                    withdrawRecordList.add(withdrawalLink);
                    amount = amount - income;
                }
                if (amount <= 0) {
                    break;
                }
            }
        }
        if (CollectionUtil.isNotEmpty(doctorOrderIncomeDetailList)) {
            Boolean flag = doctorOrderIncomeDetailService.updateBatchById(doctorOrderIncomeDetailList);
            if (!flag) {
                log.info("更新失败~");
            }
        }
        if (CollectionUtil.isNotEmpty(withdrawRecordList)) {
//                dp.saveBatch(withdrawRecordList);
            Boolean flag = doctorOrderIncomeWithdrawalLinkService.saveBatch(withdrawRecordList);
            if (!flag) {
                log.info("保存失败");
            }
        }
    }


}
